package com.example.demo.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.demo.client.SmQryClient;
import com.example.demo.client.evt.cssmqry.QryRegionListEvt;
import com.example.demo.client.evt.cssmqry.menu.UpdatePermissionByParamEvt;
import com.example.demo.client.evt.sysbasequery.IsUserNameExistEvt;
import com.example.demo.client.evt.sysbasequery.KeyEvt;
import com.example.demo.client.evt.sysbasequery.QuerySystemConfigEvt;
import com.example.demo.client.evt.sysbasequery.QueryUserEvt;
import com.example.demo.client.vm.cssmqry.menu.MenuTreeVm;
import com.example.demo.client.vm.sysbasequery.*;
import com.example.demo.domain.CsSmImportLogD;
import com.example.demo.domain.CsSmUserConfC;
import com.example.demo.domain.Password;
import com.example.demo.domain.User;
import com.example.demo.enums.*;
import com.example.demo.mapper.*;
import com.ffcs.oss.param.vm.QueryPageVm;
import com.example.demo.repository.PasswordRepository;
import com.example.demo.repository.UserRepository;
import com.example.demo.security.SecurityUtils;
import com.example.demo.service.BaseService;
import com.example.demo.service.LogService;
import com.example.demo.service.UserService;
import com.example.demo.util.Coder;
import com.example.demo.util.PasswordUtils;
import com.example.demo.web.rest.constant.DatabaseConstant;
import com.example.demo.web.rest.evt.*;
import com.example.demo.web.rest.util.CheckUtil;
import com.example.demo.web.rest.util.UserBasicUtil;
import com.example.demo.web.rest.vm.BatchUserEvt;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.google.common.collect.Lists;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.crypto.KeyGenerator;
import java.security.Key;
import java.security.SecureRandom;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

import static com.example.demo.enums.SysConfigEnum.DEFAULT_SYSTEM_STYLE_TYPE;

/**
 * Description:
 *
 * @Author zmf
 * @Date 2018/12/12  18:39
 */
@Service
@Transactional
public class UserServiceImpl extends BaseService implements UserService {
    @Value("${loginname.type}")
    private String type;
    @Autowired
    private PasswordRepository passwordRepository;
    @Autowired
    private UserRepository userRepository;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private MenuMapper menuMapper;
    @Autowired
    private LogService logService;
    @Autowired
    private SmQryClient smQryClient;
    @Autowired
    CsSmImportLogDMapper csSmImportLogDMapper;
    @Autowired
    CsSmUserConfCMapper userConfCMapper;

    @Override
    public String resetPassword(Long userId, String pwd, String loginName) throws Exception {
        String encryptPwd = Coder.encryptMD5(pwd + loginName);
        Date date = nowDateTime();
        userRepository.resetPwd(encryptPwd, date, userId);
        Password password = new Password();
        password.setUserId(userId);
        password.setPassword(encryptPwd);
        password.setInsertTime(date);
        TableIdSizeEvt evt = new TableIdSizeEvt(DatabaseConstant.TABLE_NAME_PASSWORD, DatabaseConstant.ID_SIZE);
        password.setId(baseQueryClient.getTableId(evt));
        passwordRepository.save(password);
        // update is_must_upd_pwd = Y
        userConfCMapper.update(new CsSmUserConfC().setIsMustUpdPwd("Y"),
                new LambdaQueryWrapper<CsSmUserConfC>().eq(CsSmUserConfC::getCsSmUserId, userId));
        return pwd;
    }

    @Override
    public void updateStatusAndPasswordUpdateDate(Integer status, Long userId) {

        userRepository.updateStatusAndPasswordUpdateDate(status, getPassWordUpdateTime(userId), userId);
    }

    @Override
    public void updateStatus(Integer status, Long userId) {
        userRepository.updateStatus(status, getPassWordUpdateTime(userId), userId);
    }

    @Override
    public void delUser(Long userId) {
        Integer delCount = userMapper.delUserRoleByUserId(userId);
        logger.info("删除用户与角色关系：" + delCount);
        delCount = userMapper.delUserPermissionByUserId(userId);
        logger.info("删除用户与权限关系：" + delCount);
        delCount = userMapper.delResourceByUserId(userId);
        logger.info("删除用户与资源关系：" + delCount);
        delCount = userMapper.delGroupUserByUserId(userId);
        logger.info("删除用户与用户组关系：" + delCount);
        userMapper.deleteUser(2, userId);
//        userRepository.updateStatus(2,userId);
    }

    @Override
    public void saveUser(SaveUserEvt evt) throws Exception {
        String passwordDateTime = "";
        User user = new User();
        BeanUtils.copyProperties(evt.getUserInfo(), user);
        //格式验证
        KeyEvt systemConfigEvt = new KeyEvt(SysConfigEnum.IS_USER_NAME_VERIFY.getKey());
        String value = baseQueryClient.getSysConfigValue(systemConfigEvt).getBody();
        if (value == null || SysConfigEnum.IS_USER_NAME_VERIFY.getValue().equals(value)) {
            KeyEvt userRegular = new KeyEvt(SysConfigEnum.USER_REGULAR.getKey());
            String regular = baseQueryClient.getSysConfigValue(userRegular).getBody();
            if (regular == null) {
                regular = SysConfigEnum.USER_REGULAR.getDesc();
            }
            if (!UserBasicUtil.isLoginNameLegal(user.getLoginName(), regular)) {
                throw new Exception("用户名只能包含数字、字母、下划线");
            }
        }
        if (StringUtils.isNotBlank(user.getPid()) && !UserBasicUtil.isPid(user.getPid())) {
            throw new Exception("身份证格式不正确");
        }
        if (user.getTelephone() == null || user.getTelephone().equals("")) {
            throw new Exception("电话号码不能为空");
        } else if (!UserBasicUtil.isPhone(user.getTelephone())) {
            throw new Exception("电话号码格式不正确");
        } else if (user.getUserId() == null && userMapper.isPhoneExist(user.getTelephone(), null) > 0) {
            throw new Exception("电话号码已存在");
        } else if (user.getUserId() != null && userMapper.isPhoneExist(user.getTelephone(), user.getUserId()) > 0) {
            throw new Exception("电话号码已存在");
        }
        if (!CheckUtil.isEmail(user.geteMail())) {
            throw new Exception("邮箱格式不正确");
        }

        Date date = nowDateTime();
        String userName = SecurityUtils.getCurrentUserLogin().get();
        if (evt.getUserInfo().getUserId() == null) {
            if (StringUtils.isBlank(user.getPassword())) {
                KeyEvt keyEvt = new KeyEvt(SysConfigEnum.RESET_PWD_VALUE.name());
                String pwd = baseQueryClient.getSystemConfigValueByKey(keyEvt).getBody();
                user.setPassword(pwd);
                //与编辑区分开
                evt.getUserInfo().setPassword(pwd);
            }
            if (StringUtils.isNotBlank(user.getLoginName())) {
                IsUserNameExistEvt isUserNameExistEvt = new IsUserNameExistEvt();
                isUserNameExistEvt.setLoginName(user.getLoginName());
                if (!baseQueryClient.isUserNameExist(isUserNameExistEvt).getBody()) {
                    throw new Exception("用户名已存在");
                }
            } else {
                throw new NullPointerException();
            }
            user.setPassword(Coder.encryptMD5(user.getPassword() + user.getLoginName()));
            user.setCreateUserId(getCurrentUserId());
            user.setCreateTime(date);
            user.setCreateUserName(userName);
            user.setPasswordUpdateDate(date);
            user.setStatus(UserStatus.USER_BE_REVIEWED.getValue());
        }
        // TODO: 前端暂无该字段，先写死，下一版修改
        user.setOrgId(1L);
        if (StringUtils.isNotBlank(evt.getUserInfo().getCreateTime()) && user.getCreateTime() == null) {
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            user.setCreateTime(formatter.parse(evt.getUserInfo().getCreateTime()));
        }

        user.setUpdateTime(date);
        user.setUpdateUserName(userName);
//        userRepository.save(user);
        if (user.getUserId() == null) {
            //新增
            TableIdSizeEvt tableIdSizeEvt = new TableIdSizeEvt(DatabaseConstant.TABLE_NAME_USER, DatabaseConstant.ID_SIZE);
            user.setUserId(baseQueryClient.getTableId(tableIdSizeEvt));
            userMapper.saveUser(user);
        } else {
            //编辑
            userMapper.updateUser(user);
        }


        //编辑状态密码更新时间不做改变
//        if(StringUtils.isBlank(evt.getUserInfo().getPassword())){
//            //取数据库的更新时间
//            Date updateTime = getPassWordUpdateTime(user.getUserId());
////            userRepository.updatePasswordDateTime(updateTime,user.getUserId());
//            userMapper.updatePasswordDateTime(updateTime,user.getUserId());
//        }

        Long userId = user.getUserId();
        RelationEvt relationEvt = new RelationEvt();
        relationEvt.setId(userId);
        // 删除用户组与用户的关系
        if (evt.getDelGroupIds() != null && !evt.getDelGroupIds().isEmpty()) {
            relationEvt.setRelateIds(evt.getDelGroupIds());
            userMapper.delGroupUserByUserIdAndGroupIds(relationEvt);
        }
        // 增加用户组与用户的关系
        if (evt.getAddGroupIds() != null && !evt.getAddGroupIds().isEmpty()) {
//        if (!CollectionUtils.isEmpty(evt.getAddGroupIds())) {
            //剔除前端传值为空
            Iterator<String> it = evt.getAddGroupIds().iterator();
            while (it.hasNext()) {
                if (StringUtils.isBlank(it.next())) {
                    it.remove();
                }
            }
            relationEvt.setRelateIds(evt.getAddGroupIds());
            userMapper.addGroupUserByUserIdAndGroupIds(relationEvt);
        }
        //删除用户和权限关系
        if (evt.getDelPermissionIds() != null && !evt.getDelPermissionIds().isEmpty()) {
            relationEvt.setRelateIds(evt.getDelPermissionIds());
            userMapper.delUserPermissionByUserIdAndPermissionIds(relationEvt);
        }
        //添加用户和权限关系
        if (evt.getAddPermissionIds() != null && !evt.getAddPermissionIds().isEmpty()) {
            relationEvt.setRelateIds(evt.getAddPermissionIds());
            userMapper.addUserPermissionByUserIdAndPermissionIds(relationEvt);
        }
        //删除用户和角色关系
        if (evt.getDelRoleIds() != null && !evt.getDelRoleIds().isEmpty()) {
            relationEvt.setRelateIds(evt.getDelRoleIds());
            userMapper.delUserRoleByUserIdAndRoleIds(relationEvt);
        }
        //添加用户和角色关系
        if (evt.getAddRoleIds() != null && !evt.getAddRoleIds().isEmpty()) {
            relationEvt.setRelateIds(evt.getAddRoleIds());
            userMapper.addUserRoleByUserIdAndRoleIds(relationEvt);
        }

        ResourceRelationEvt resourceRelationEvt = new ResourceRelationEvt();
        resourceRelationEvt.setId(userId);
        resourceRelationEvt.setType(ResourceObjectTypeEnum.USER_REF.getValue());
        resourceRelationEvt.setCreateUserName(userName);
        resourceRelationEvt.setUpdateUserName(userName);
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String time = format.format(new Date());
        resourceRelationEvt.setCreateTime(time);
        resourceRelationEvt.setUpdateTime(time);
        //删除用户和资源关系
        if (evt.getDelResource() != null && !evt.getDelResource().isEmpty()) {
            resourceRelationEvt.setList(evt.getDelResource());
            userMapper.delUserResource(resourceRelationEvt);
        }
        // 增加用户和资源关系
        if (evt.getAddResource() != null && !evt.getAddResource().isEmpty()) {
            resourceRelationEvt.setList(evt.getAddResource());
            userMapper.addUserResource(resourceRelationEvt);
        }

        //添加用户安全策略信息表
        Long confId = userMapper.getUserConfId(userId);
        evt.getUserPolicy().setUserId(userId);
        UserPolicyEvt policy = setPolicyDefalut(evt.getUserPolicy());
        if (confId == null) {
            TableIdSizeEvt tableIdSizeEvt = new TableIdSizeEvt(DatabaseConstant.TABLE_NAME_USER_CONF, DatabaseConstant.ID_SIZE);
            policy.setConfId(baseQueryClient.getTableId(tableIdSizeEvt));
            //设置默认系统风格
            List<SystemConfigVm> systemConfigVmList = baseQueryClient.querySystemConfig(new QuerySystemConfigEvt()).getBody().getRecords();
            for (SystemConfigVm vm :
                    systemConfigVmList) {
                if (DEFAULT_SYSTEM_STYLE_TYPE.getKey().equals(vm.getKey())) {
                    policy.setSystemStyleType(Integer.parseInt(vm.getValue()));
                }
            }
            userMapper.addUserSecurityPolicy(policy);
        } else {
            policy.setConfId(confId);
            userMapper.updateUserConf(policy);
        }

        UpdatePermissionByParamEvt updatePermissionByParamEvt = new UpdatePermissionByParamEvt();
        updatePermissionByParamEvt.setType(PermissionTypeEnum.USER.getValue());
        updatePermissionByParamEvt.setId(String.valueOf(userId));
        baseQueryClient.updatePermissionByParam(updatePermissionByParamEvt);
    }

    @Override
    public void saveBatchUserPermissions(SaveBatchUserPermissionEvt evt) {
        // 半勾选 ---->全选/不选
        Collection partToAllOrNone = CollectionUtils
                .subtract(evt.getOldPartPermIds(), evt.getNewPartPermIds());
        // 全选---->不选
        Collection allToNone = CollectionUtils
                .subtract(evt.getOldPermissionIds(), evt.getNewPermissionIds());
        // 半勾选 ---->不选,也有从CM_SM_USER_PERMISSION_D删除
        List<String> partToNone = new ArrayList<>();
        for (Object id : partToAllOrNone) {
            String partId = id.toString();
            if (!evt.getNewPermissionIds().contains(partId)) {
                partToNone.add(partId);
            }
        }
        //全选/半勾选 ---->不选->删除
        List<String> delPermissionIds = new ArrayList<>();
        delPermissionIds.addAll(allToNone);
        delPermissionIds.addAll(partToNone);
        //半勾选/不选 ---->全选->添加
        Collection partOrNoneToAll = CollectionUtils
                .subtract(evt.getNewPermissionIds(), evt.getOldPermissionIds());
        //删除 由全选、半勾-》不选
        if (!evt.getSelectUserIds().isEmpty() && delPermissionIds.size() > 0) {
            userMapper.delUserPermission(evt.getSelectUserIds(), delPermissionIds);
        }
        //删除 由半勾选变成 ---->到都选的功能
        if (!evt.getSelectUserIds().isEmpty() && partOrNoneToAll.size() > 0) {
            List<String> addPermissionIds = new ArrayList<>(partOrNoneToAll);
            userMapper.delUserPermission(evt.getSelectUserIds(), addPermissionIds);
            for (String userId : evt.getSelectUserIds()) {
                RelationEvt relationEvt = new RelationEvt();
                relationEvt.setId(Long.parseLong(userId));
                relationEvt.setRelateIds(addPermissionIds);
                userMapper.addUserPermissionByUserIdAndPermissionIds(relationEvt);
            }
        }
    }

    @Override
    public void saveResetPasswordLog(OperateLogEvt evt) {
        evt.setOperateComment("RESETPASSWORD");
//        evt.setOperateResultStatus("成功");
        evt.setOperateAction("重置密码");
        evt.setModuleType("用户管理");
        evt.setRemarks("用户管理");
        logService.saveOperateLog(evt);
    }

    @Override
    public QueryPageVm<QueryUserVm> queryUser(QueryUserEvt evt) {
        QueryPageVm<QueryUserVm> queryPageVm;
        if (evt.getPageNo() != null && evt.getPageSize() != null && evt.isCountTotal()) {
            Page page = PageHelper.startPage(evt.getPageNo(), evt.getPageSize(), evt.isCountTotal());
            queryPageVm = QueryPageVm.getInstance(evt, userMapper.queryUser(evt), page.getTotal());
        } else {
            queryPageVm = QueryPageVm.getInstance(evt, userMapper.queryUser(evt), 0L);
        }
        setNameByIdList(queryPageVm.getRecords());
        return queryPageVm;
    }

    @Override
    public QueryUserVm getLoginUserInfo() {
        List<QueryUserVm> list = userMapper.getUserByLoginName(SecurityUtils.getCurrentUserLogin().get());
        if (list != null && list.size() == 1) {
            return setNameByIdList(list).get(0);
        }
        return null;
    }

    List<QueryUserVm> setNameByIdList(List<QueryUserVm> users) {
        Set<String> roleIdsSet;
        Set<String> menuIdsSet;
        for (QueryUserVm vm :
                users) {
            if (StringUtils.isBlank(vm.getRoleIds())) {
                continue;
            }
            String[] roleIds = vm.getRoleIds().split(",");
            roleIdsSet = new HashSet<>(Arrays.asList(roleIds));
            List<RoleTreeVm> roleList = roleMapper.getRoleByIds(roleIdsSet);
            String roleName = "";
            for (RoleTreeVm role :
                    roleList) {
                roleName += ("," + role.getRoleName());
            }
            vm.setRoleName(StringUtils.isBlank(roleName) ? null : roleName.substring(1));
        }
        for (QueryUserVm vm :
                users) {
            if (StringUtils.isBlank(vm.getMenuIds())) {
                continue;
            }
            String[] menuIds = vm.getMenuIds().split(",");
            menuIdsSet = new HashSet<>(Arrays.asList(menuIds));
            List<MenuTreeVm> menuList = menuMapper.getMenuByIds(menuIdsSet);
            String menuName = "";
            for (MenuTreeVm menu :
                    menuList) {
                menuName += ("," + menu.getNameCn());
            }
            vm.setMenuName(StringUtils.isBlank(menuName) ? null : menuName.substring(1));
        }
        return users;
    }

    @Override
    public void updateStatusMapper(Integer status, Long userId) throws ParseException {
        userMapper.updateStatus(status, userId, nowDateTime());
    }

    /**
     * 查询用户近期使用的五个密码
     *
     * @param userId
     */
    @Override
    public List<String> getNearlyFivePwd(Long userId) {
        return userMapper.getNearlyFivePwd(userId);
    }

    /**
     * 保存用户的密码修改信息
     *
     * @param userId
     * @param newPassword
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveUserPwdInfo(Long userId, String newPassword) {
        //将当前密码修改保存到密码修改表中
        TableIdSizeEvt tableIdSizeEvt = new TableIdSizeEvt(DatabaseConstant.TABLE_NAME_PASSWORD, DatabaseConstant.ID_SIZE);
        baseQueryClient.getTableId(tableIdSizeEvt);
        userMapper.insertPasswrodInfo(baseQueryClient.getTableId(tableIdSizeEvt), userId, newPassword);
        //更新当前登录用户密码信息
        userMapper.updUserPwdInfo(userId, newPassword);
        return true;
    }

    @Override
    public String importUser(List<Map<String, Object>> paramsList, CsSmImportLogD csSmImportLogD) {
        String allStr = "";
        List<String> tempStr = Lists.newArrayList();
        List<String> userIds = new ArrayList<>();
        Map<String, Object> params;
        KeyEvt systemConfigEvt = new KeyEvt(SysConfigEnum.IS_USER_NAME_VERIFY.getKey());
        String value = baseQueryClient.getSysConfigValue(systemConfigEvt).getBody();
        List<Map<String, Object>> insertDatas = Lists.newArrayList();
        for (int i = 0; i < paramsList.size(); i++) {
            params = paramsList.get(i);
            //用户名验证
            IsUserNameExistEvt existEvt = new IsUserNameExistEvt();
            String loginName = String.valueOf(params.get("loginName"));
            existEvt.setLoginName(loginName);
            Boolean isExist = baseQueryClient.isUserNameExist(existEvt).getBody();
            if (!isExist) {
                tempStr.add("第" + params.get("index") + "行用户名已存在");
            }
            if (value == null || SysConfigEnum.IS_USER_NAME_VERIFY.getValue().equals(value)) {
                KeyEvt userRegular = new KeyEvt(SysConfigEnum.USER_REGULAR.getKey());
                String regular = baseQueryClient.getSysConfigValue(userRegular).getBody();
                if (regular == null) {
                    regular = SysConfigEnum.USER_REGULAR.getDesc();
                }
                if (!UserBasicUtil.isLoginNameLegal(loginName, regular)) {
                    tempStr.add("第" + params.get("index") + "行用户名格式出错");
                }
            }
            //电话号码验证
            String telephone = String.valueOf(params.get("telephone"));
            if (!UserBasicUtil.isPhone(telephone)) {
                tempStr.add("第" + params.get("index") + "行电话号码错误");
            } else if (userMapper.isPhoneExist(telephone, null) > 0) {
                tempStr.add("第" + params.get("index") + "行电话号码已存在");
            }
            //邮箱验证
            String email = String.valueOf(params.get("eMail"));
            if (!CheckUtil.isEmail(email)) {
                tempStr.add("第" + params.get("index") + "行邮箱错误");
            }
            //身份证验证
            String pid = String.valueOf(params.get("pid"));
            if (StringUtils.isNotBlank(pid) && !UserBasicUtil.isPid(pid)) {
                tempStr.add("第" + params.get("index") + "行身份证错误");
            }
            //密码验证
            String password = String.valueOf(params.get("password"));
            if (StringUtils.isNotBlank(password) && !PasswordUtils.isPasswordStrong(password)) {
                tempStr.add("第" + params.get("index") + "行密码为弱密码");
            }
            if (CollectionUtils.isNotEmpty(tempStr)) {
                allStr += StringUtils.join(tempStr, ",");
                tempStr.clear();
                allStr += "\n";
            } else {
                insertDatas.add(params);
            }
        }
        if (StringUtils.isNotBlank(allStr)) {
            csSmImportLogD.setStatus(0);
            csSmImportLogD.setRemark(allStr);
            csSmImportLogDMapper.updateById(csSmImportLogD);
            return allStr;
        }
        //设置默认密码
        KeyEvt keyEvt = new KeyEvt(SysConfigEnum.RESET_PWD_VALUE.name());
        String defaultPwd = baseQueryClient.getSystemConfigValueByKey(keyEvt).getBody();
        if (StringUtils.isBlank(defaultPwd)) {
            defaultPwd = SysConfigEnum.RESET_PWD_VALUE.getValue();
        }
        //获取用户表与用户配置表当前可用id以及导入数据大小的缓存id
        TableIdSizeEvt tableIdSizeEvt = new TableIdSizeEvt(DatabaseConstant.TABLE_NAME_USER, insertDatas.size());
        Long userNowId = baseQueryClient.getTableId(tableIdSizeEvt);
        tableIdSizeEvt = new TableIdSizeEvt(DatabaseConstant.TABLE_NAME_USER_CONF, insertDatas.size());
        Long userConfNowId = baseQueryClient.getTableId(tableIdSizeEvt);
        //用户配置表默认信息
        UserPolicyEvt policy = setPolicyDefalut(new UserPolicyEvt());
        policy.setSystemStyleType(0);
        //用户字典值信息
        UserStaticDataVm userStaticDataVm = baseQueryClient.getUserStaticData().getBody();
        for (int i = 0; i < insertDatas.size(); i++) {
            params = insertDatas.get(i);

            if (userMapper.selectCountByLoginName(String.valueOf(params.get("loginName"))) > 0) {
                tempStr.add("第" + params.get("index") + "行用户名已存在");
            }
            if (userMapper.isPhoneExist(String.valueOf(params.get("telephone")), null) > 0) {
                tempStr.add("第" + params.get("index") + "行电话号码已存在");
            }

            User user = new User();
            try {
                //区域验证
                Long regionId;
                String fullRegionId = ",";
                String fullRegionName = "";
                QryRegionListEvt regionEvt = new QryRegionListEvt();
                regionEvt.setRegionName(fullRegionName);
                regionEvt.setMatchRule(3);
                List list = (List) baseQueryClient.qryRegionList(regionEvt).getBody();

                Map<String, Object> map = (Map<String, Object>) list.get(0);
                regionId = Long.parseLong(String.valueOf(map.get("regionId")));
                fullRegionId = fullRegionId + regionId + ",";
                String regionName = String.valueOf(params.get("regionType"));
                if (StringUtils.isNotBlank(regionName) && !Objects.equals("集团", regionName)) {
                    regionEvt.setRegionName(regionName);
                    Long lastRegionId = null;
                    String parentId = "-1";
                    List<String> regionIdList = new ArrayList<>();
                    //倒查
                    String childrenId = "";
                    String childrenName = "";
                    while (!fullRegionId.contains(parentId)) {
                        list = (List) baseQueryClient.qryRegionList(regionEvt).getBody();
                        regionIdList.clear();
                        if (list == null || list.size() == 0) {
                            tempStr.add("第" + params.get("index") + "行区域数据错误，result size:" + list.size());
                        } else {
                            map = (Map<String, Object>) list.get(0);
                            if (lastRegionId == null) {
                                lastRegionId = Long.parseLong(String.valueOf(map.get("regionId")));
                            }
                            childrenId = map.get("regionId") + "," + childrenId;
                            childrenName = "/" + map.get("regionName") + childrenName;
                        }
                        parentId = String.valueOf(map.get("parentId"));
                        regionIdList.add(parentId);
                        regionEvt.setRegionIdList(regionIdList);
                        regionEvt.setRegionName(null);
                    }
                    regionId = lastRegionId;
                    fullRegionId += childrenId;
                    fullRegionName += childrenName;
                }

                logger.info("区域验证通过");

                //对区域id判断，最多取到省级
                String roleRegionId = "";
                if (regionId == 100000) {
                    roleRegionId = String.valueOf(regionId);
                } else {
                    int indexStart = StringUtils.ordinalIndexOf(fullRegionId, ",", 2);
                    int indexEnd = StringUtils.ordinalIndexOf(fullRegionId, ",", 3);
                    roleRegionId = fullRegionId.substring(indexStart + 1, indexEnd);
                }
                //角色验证
                String allRole = String.valueOf(params.get("role"));
                if (StringUtils.isNotBlank(allRole)) {
                    String[] rolesList = allRole.split(",");
                    for (String rolesName : rolesList) {
                        if (roleMapper.isExistRoleName(rolesName, roleRegionId) == null || roleMapper.isExistRoleName(rolesName, roleRegionId).size() == 0) {
                            tempStr.add("第" + params.get("index") + "行" + rolesName + "角色不存在");
                        }
                    }
                }
                if (CollectionUtils.isNotEmpty(tempStr)) {
                    allStr += StringUtils.join(tempStr, ",") + "\n";
                    tempStr.clear();
                } else {
                    //保存用户
                    String loginName = String.valueOf(params.get("loginName"));
                    String telephone = String.valueOf(params.get("telephone"));
                    String email = String.valueOf(params.get("eMail"));
                    user.setUserId(userNowId++);
                    user.setLoginName(loginName);
                    user.setAlias(String.valueOf(params.get("alias")));
                    user.setStatus(UserStatus.USER_BE_REVIEWED.getValue());

                    String password = String.valueOf(params.get("password"));
                    if (StringUtils.isNotBlank(password)) {
                        user.setPassword(Coder.encryptMD5(password + loginName));
                    } else {
                        user.setPassword(Coder.encryptMD5(defaultPwd + loginName));
                    }

                    user.seteMail(email);
                    user.setTelephone(telephone);

                    String userType = codeTrans(String.valueOf(params.get("userType")), userStaticDataVm.getUserType());
                    if (StringUtils.isBlank(userType)) {
                        user.setUserType(DatabaseConstant.USER_TYPE_DEFALUT_CODE);
                    } else {
                        user.setUserType(Integer.parseInt(userType));
                    }
                    String company = String.valueOf(params.get("arg1"));
                    user.setArg1(codeTrans(company, userStaticDataVm.getCompany()));

                    user.setDescription(String.valueOf(params.get("description")));
                    user.setPid(String.valueOf(params.get("pid")));
                    user.setRegionId(regionId);
                    user.setFullRegion(fullRegionId);
                    user.setFullRegionName(fullRegionName);
                    user.setOrgId(1L);
                    user.setDefaultPwd(defaultPwd);

                    Date nowDate = nowDateTime();
                    String username = SecurityUtils.getCurrentUserLogin().get();
                    user.setPasswordUpdateDate(nowDate);
                    user.setCreateTime(nowDate);
                    user.setUpdateTime(nowDate);
                    user.setCreateUserName(username);
                    user.setUpdateUserName(username);
                    user.setCreateUserId(getCurrentUserId());

                    User saveUser = userRepository.saveAndFlush(user);
                    userIds.add(String.valueOf(saveUser.getUserId()));
                    logger.info("保存用户信息成功");

                    policy.setConfId(userConfNowId++);
                    policy.setUserId(saveUser.getUserId());
                    List<SystemConfigVm> systemConfigVmList = baseQueryClient.querySystemConfig(new QuerySystemConfigEvt()).getBody().getRecords();
                    for (SystemConfigVm vm :
                            systemConfigVmList) {
                        if (DEFAULT_SYSTEM_STYLE_TYPE.getKey().equals(vm.getKey())) {
                            policy.setSystemStyleType(Integer.parseInt(vm.getValue()));
                        }
                    }
                    userMapper.addUserSecurityPolicy(policy);
                    //保存用户角色关系
                    String role = String.valueOf(params.get("role"));
                    if (StringUtils.isNotBlank(role)) {
                        List<String> roles = new ArrayList<>();
                        String[] roleList = role.split(",");
                        for (String roleName : roleList) {
                            List<String> ids = roleMapper.isExistRoleName(roleName, roleRegionId);
                            for (String id : ids) {
                                roles.add(id);
                            }
                        }
                        RelationEvt evt = new RelationEvt();
                        evt.setId(saveUser.getUserId());
                        evt.setRelateIds(roles);
                        roleMapper.addRolesToUser(evt);
                    }
                }
            } catch (Exception e) {
                logger.error("用户保存异常", e);
                csSmImportLogD.setStatus(0);
                csSmImportLogD.setRemark("第" + params.get("index") + "行保存错误！请联系管理员");
                csSmImportLogDMapper.updateById(csSmImportLogD);
                return ("第" + params.get("index") + "行保存错误！请联系管理员");
            }
        }
        if (StringUtils.isNotBlank(allStr)) {
            csSmImportLogD.setStatus(0);
            csSmImportLogD.setRemark(allStr);
            csSmImportLogDMapper.updateById(csSmImportLogD);
            return allStr;
        }
        baseQueryClient.updatePermission(userIds);
        return allStr;
    }

    public String codeTrans(String descName, List<CodeVm> list) {
        if (StringUtils.isBlank(descName)) {
            return null;
        }
        for (CodeVm vm :
                list) {
            if (Objects.equals(descName, vm.getDescName())) {
                return vm.getValue();
            }
        }
        return null;
    }

    /**
     * 根据用户id获取密码更新时间
     */
    public Date getPassWordUpdateTime(Long userId) {
        String passwordDateTime = userMapper.getPasswordDateTime(userId);
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            Date parsePassDateTime = formatter.parse(passwordDateTime);
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(parsePassDateTime);
            //入库会默认减少 8 小时  去掉这个操作
            calendar.add(Calendar.HOUR_OF_DAY, +8);
            return calendar.getTime();
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    public UserPolicyEvt setPolicyDefalut(UserPolicyEvt evt) {
        UserPolicyEvt policy = new UserPolicyEvt();
        BeanUtils.copyProperties(evt, policy);
        policy.setUserId(evt.getUserId());
        KeyEvt keyEvt;
        if (StringUtils.isBlank(policy.getMaxOnlineSessionNum())) {
            keyEvt = new KeyEvt(SysConfigEnum.MAX_ONLINE_SESSION_NUM.name());
            policy.setMaxOnlineSessionNum(baseQueryClient.getSystemConfigValueByKey(keyEvt).getBody());
        }
        if (StringUtils.isBlank(policy.getAccountEffective())) {
            keyEvt = new KeyEvt(SysConfigEnum.ACCOUNT_VALID_DAYS.name());
            policy.setAccountEffective(baseQueryClient.getSystemConfigValueByKey(keyEvt).getBody());
        }
        if (StringUtils.isBlank(policy.getPwdEffective())) {
            keyEvt = new KeyEvt(SysConfigEnum.PWD_VALID_DAYS.name());
            policy.setPwdEffective(baseQueryClient.getSystemConfigValueByKey(keyEvt).getBody());
        }
        if (StringUtils.isBlank(policy.getPwdPromptDays())) {
            keyEvt = new KeyEvt(SysConfigEnum.PWD_PROMPT_DAYS.name());
            policy.setPwdPromptDays(baseQueryClient.getSystemConfigValueByKey(keyEvt).getBody());
        }
        if (StringUtils.isBlank(policy.getIsMustUpdPwd())) {
            keyEvt = new KeyEvt(SysConfigEnum.CHANGE_PWD_NEXTTIME_LOGIN.name());
            policy.setIsMustUpdPwd(baseQueryClient.getSystemConfigValueByKey(keyEvt).getBody());
        }
        if (StringUtils.isBlank(policy.getAccountLockout())) {
            keyEvt = new KeyEvt(SysConfigEnum.ACCOUNT_LOCKOUT.name());
            policy.setAccountLockout(baseQueryClient.getSystemConfigValueByKey(keyEvt).getBody());
        }
        if (StringUtils.isBlank(policy.getAccountDisabled())) {
            keyEvt = new KeyEvt(SysConfigEnum.ACCOUNT_DISABLED.name());
            policy.setAccountDisabled(baseQueryClient.getSystemConfigValueByKey(keyEvt).getBody());
        }
        return policy;
    }

    public Date nowDateTime() throws ParseException {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String nowDate = format.format(new Date());
        return format.parse(nowDate);
    }

    public static void main(String[] args) {
        String passwordDateTime = "2018-08-27 16:05:45";
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            Date parsePassDateTime = formatter.parse(passwordDateTime);
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(parsePassDateTime);
            calendar.add(Calendar.HOUR_OF_DAY, -8);
            System.out.println("calendar.getTime() = " + calendar.getTime());
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }


    @Override
    public void updateMustUpdStatus() {
        QueryUserEvt evt = new QueryUserEvt();
        evt.setLoginName(SecurityUtils.getCurrentUserLogin().get());
        List<QueryUserVm> users = baseQueryClient.queryUser(evt).getBody().getRecords();
        List<Long> allUserId = new ArrayList();
        for (QueryUserVm user : users) {
            allUserId.add(user.getUserId());
        }
        userMapper.updateMustUpdStatus(allUserId, YesOrNo.Y.getValue());
    }

    @Override
    public String batchUser(BatchUserEvt evt) {
        String msg = "";
        switch (BatchStatusEnum.getByValue(evt.getOperation())) {
            case USER_IN_USE:
                //批量操作审核通过，或者解锁时传入参数1，需要用户处于待审核，或锁定状态
                List<UserModifyEvt> collect = new ArrayList<>();
                for (UserModifyEvt collectEvt : evt.getUserModifyList()) {
                    collect.add(collectEvt);
                }
                collect.removeIf(o -> o.getStatus().toString().equals(UserStatus.USER_BE_REVIEWED.getValue().toString()) || o.getStatus().toString().equals(UserStatus.USER_LOCK.getValue().toString()));
                for (UserModifyEvt userModifyEvt : collect) {
                    msg = msg + userModifyEvt.getUserName() + ",";
                }
                evt.setUserModifyList(evt.getUserModifyList()
                        .stream()
                        .filter(o -> o.getStatus().toString().equals(UserStatus.USER_BE_REVIEWED.getValue().toString()) || o.getStatus().toString().equals(UserStatus.USER_LOCK.getValue().toString()))
                        .collect(Collectors.toList()));
                break;
            case USER_REJECT:
                //批量操作审核不通过需要用户处于待审核
                List<UserModifyEvt> collect1 = new ArrayList<>();
                for (UserModifyEvt collectEvt : evt.getUserModifyList()) {
                    collect1.add(collectEvt);
                }
                collect1.removeIf(o -> o.getStatus().toString().equals(UserStatus.USER_BE_REVIEWED.getValue().toString()));
                for (UserModifyEvt userModifyEvt : collect1) {
                    msg = msg + userModifyEvt.getUserName() + ",";
                }
                evt.setUserModifyList(evt.getUserModifyList()
                        .stream()
                        .filter(o -> o.getStatus().toString().equals(UserStatus.USER_BE_REVIEWED.getValue().toString()))
                        .collect(Collectors.toList()));
                break;
            case USER_LOCK:
                //批量操作锁定需要用户处于在用状态
                List<UserModifyEvt> collect2 = new ArrayList<>();
                for (UserModifyEvt collectEvt : evt.getUserModifyList()) {
                    collect2.add(collectEvt);
                }
                collect2.removeIf(o -> o.getStatus().toString().equals(UserStatus.USER_IN_USE.getValue().toString()));
                for (UserModifyEvt userModifyEvt : collect2) {
                    msg = msg + userModifyEvt.getUserName() + ",";
                }
                evt.setUserModifyList(evt.getUserModifyList()
                        .stream()
                        .filter(o -> o.getStatus().toString().equals(UserStatus.USER_IN_USE.getValue().toString()))
                        .collect(Collectors.toList()));
                break;
        }
        return msg;
    }

    public static Key getKey(String keySeed) {
        if (keySeed == null) {
            keySeed = System.getenv("AES_SYS_KEY");
        }
        if (keySeed == null) {
            keySeed = System.getProperty("AES_SYS_KEY");
        }
        if (keySeed == null || keySeed.trim().length() == 0) {
            keySeed = "abcd1234!@#$";// 默认种子
        }
        try {
            SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
            secureRandom.setSeed(keySeed.getBytes());
            KeyGenerator generator = KeyGenerator.getInstance("AES");
            generator.init(secureRandom);
            return generator.generateKey();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

}
